/*!
    \file    dmx512_led_controller.c
    \brief   DMX512 LED控制器实现文件 - 集成DMX512接收器与LED灯带控制

    \version 2025-01-20, V1.0.0, DMX512 LED控制器 for GD32C231C
*/

#include "dmx512_led_controller.h"
#include "systick.h"
#include <string.h>
#include <stdio.h>

/* 全局DMX512 LED控制器句柄 */
dmx512_led_handle_t g_dmx512_led_controller;

/* 静态变量 */
static uint8_t s_last_dmx_data[DMX512_RX_BUFFER_SIZE];  /* 上次DMX数据缓存 */
static bool s_data_changed = false;                     /* 数据变化标志 */

/* 静态函数声明 */
static void dmx512_led_controller_dmx_frame_callback(uint8_t *data, uint16_t length);
static void dmx512_led_controller_dmx_error_callback(dmx512_rx_error_t error);
static void dmx512_led_controller_update_stats(void);
static uint16_t dmx512_led_controller_map_direct(uint8_t *dmx_data, uint16_t dmx_length, 
                                                rgb_color_t *led_colors, uint16_t led_count);
static uint16_t dmx512_led_controller_map_scaled(uint8_t *dmx_data, uint16_t dmx_length, 
                                                rgb_color_t *led_colors, uint16_t led_count);
static uint16_t dmx512_led_controller_map_replicated(uint8_t *dmx_data, uint16_t dmx_length, 
                                                    rgb_color_t *led_colors, uint16_t led_count);

/*!
    \brief      初始化DMX512 LED控制器
    \param[in]  config: 配置参数指针
    \param[out] none
    \retval     none
*/
void dmx512_led_controller_init(dmx512_led_config_t *config)
{
    /* 初始化控制器句柄 */
    memset(&g_dmx512_led_controller, 0, sizeof(dmx512_led_handle_t));
    
    /* 复制配置 */
    if (config != NULL) {
        memcpy(&g_dmx512_led_controller.config, config, sizeof(dmx512_led_config_t));
    } else {
        /* 使用默认配置 */
        dmx512_led_controller_get_default_config(&g_dmx512_led_controller.config);
    }
    
    /* 注意：DMX512接收器将在start()函数中初始化，避免启动时立即激活 */
    
    /* 初始化LED颜色缓冲区 */
    memset(g_dmx512_led_controller.led_colors, 0, sizeof(g_dmx512_led_controller.led_colors));
    
    /* 初始化数据变化检测 */
    memset(s_last_dmx_data, 0, sizeof(s_last_dmx_data));
    s_data_changed = false;
    
    g_dmx512_led_controller.initialized = true;
    g_dmx512_led_controller.enabled = true;
    
    printf("\r\nDMX512 LED控制器初始化完成");
    printf("\r\n  模式: %s", dmx512_led_controller_get_mode_string(g_dmx512_led_controller.config.mode));
    printf("\r\n  输出: %s", dmx512_led_controller_get_output_string(g_dmx512_led_controller.config.output));
    printf("\r\n  起始通道: %d", g_dmx512_led_controller.config.start_channel);
    printf("\r\n  DMX512 LED数量: %d", g_dmx512_led_controller.config.dmx_led_count);
    printf("\r\n  WS2812 LED数量: %d", g_dmx512_led_controller.config.ws2812_led_count);
}

/*!
    \brief      反初始化DMX512 LED控制器
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_led_controller_deinit(void)
{
    /* 停止控制器 */
    dmx512_led_controller_stop();
    
    /* 反初始化DMX512接收器（如果已初始化） */
    dmx512_rx_deinit();
    
    /* 重置句柄 */
    memset(&g_dmx512_led_controller, 0, sizeof(dmx512_led_handle_t));
    
    printf("\r\nDMX512 LED控制器已反初始化");
}

/*!
    \brief      启动DMX512 LED控制器
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_led_controller_start(void)
{
    if (g_dmx512_led_controller.initialized && !g_dmx512_led_controller.enabled) {
        g_dmx512_led_controller.enabled = true;
        
        /* 初始化DMX512接收器（如果尚未初始化） */
        static bool rx_initialized = false;
        if (!rx_initialized) {
            dmx512_rx_init();
            
            /* 设置DMX512接收器回调函数 */
            dmx512_rx_set_frame_callback(dmx512_led_controller_dmx_frame_callback);
            dmx512_rx_set_error_callback(dmx512_led_controller_dmx_error_callback);
            
            rx_initialized = true;
            printf("\r\nDMX512接收器已初始化");
        }
        
        /* 启动DMX512接收器 */
        dmx512_rx_start();
        
        printf("\r\nDMX512 LED控制器已启动");
    }
}

/*!
    \brief      停止DMX512 LED控制器
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_led_controller_stop(void)
{
    if (g_dmx512_led_controller.enabled) {
        g_dmx512_led_controller.enabled = false;
        
        /* 停止DMX512接收器 */
        dmx512_rx_stop();
        
        /* 关闭所有LED */
        memset(g_dmx512_led_controller.led_colors, 0, sizeof(g_dmx512_led_controller.led_colors));
        dmx512_led_controller_update_leds(true);
        
        printf("\r\nDMX512 LED控制器已停止");
    }
}

/*!
    \brief      处理接收到的DMX512帧
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_led_controller_process_frame(void)
{
    if (!g_dmx512_led_controller.enabled) {
        return;  /* 控制器未启用，静默返回 */
    }
    
    if (!dmx512_rx_is_frame_ready()) {
        return;  /* 没有新帧，正常情况 */
    }
    
    uint8_t dmx_buffer[DMX512_RX_BUFFER_SIZE];
    uint16_t dmx_length = dmx512_rx_copy_data(dmx_buffer, sizeof(dmx_buffer));
    
    /* 添加基本状态输出，但控制频率 */
    static uint32_t process_counter = 0;
    process_counter++;
    
    if (dmx_length > 0) {
        /* 每100帧输出一次基本状态 */
        if (process_counter % 100 == 0) {
            printf("\r\n[INFO] 处理DMX帧: 长度=%d, 起始码=0x%02X", dmx_length, dmx_buffer[0]);
        }
        
        /* 检查数据是否有变化 */
        if (memcmp(dmx_buffer, s_last_dmx_data, dmx_length) != 0) {
            memcpy(s_last_dmx_data, dmx_buffer, dmx_length);
            s_data_changed = true;
            
            /* 每50次数据变化输出一次 */
            if (process_counter % 50 == 0) {
                printf("\r\n[INFO] DMX数据变化，更新LED");
            }
            
            /* 映射DMX数据到LED颜色 */
            uint16_t led_count = dmx512_led_controller_map_data(dmx_buffer, dmx_length, 
                                                              g_dmx512_led_controller.led_colors, 
                                                              DMX512_LED_MAX_LEDS);
            
            /* 应用亮度调整 */
            dmx512_led_controller_apply_brightness(g_dmx512_led_controller.led_colors, 
                                                  led_count, 
                                                  g_dmx512_led_controller.config.brightness);
            
            /* 更新LED输出 */
            dmx512_led_controller_update_leds(false);
            
            /* 更新统计信息 */
            g_dmx512_led_controller.stats.frames_updated++;
            dmx512_led_controller_update_stats();
            
            /* 调用帧更新回调 */
            if (g_dmx512_led_controller.frame_update_callback != NULL) {
                g_dmx512_led_controller.frame_update_callback(led_count, g_dmx512_led_controller.led_colors);
            }
        }
        
        g_dmx512_led_controller.stats.frames_processed++;
    } else {
        /* 每200次无数据时输出一次 */
        if (process_counter % 200 == 0) {
            printf("\r\n[WARN] 未接收到DMX数据");
        }
    }
    
    /* 标记帧已处理 */
    dmx512_rx_frame_processed();
}

/*!
    \brief      更新LED输出
    \param[in]  force_update: 强制更新标志
    \param[out] none
    \retval     none
*/
void dmx512_led_controller_update_leds(bool force_update)
{
    /* 声明外部全局变量 */
    extern bool g_led_strip_enabled;
    
    if (!g_dmx512_led_controller.enabled && !force_update) {
        return;
    }
    
    /* 检查全局灯带开启状态，只有开启时才实际发送数据 */
    if (!g_led_strip_enabled && !force_update) {
        return;
    }
    
    dmx512_led_output_t output = g_dmx512_led_controller.config.output;
    
    /* 更新DMX512灯带 */
    if (output & DMX512_LED_OUTPUT_DMX512) {
        uint16_t dmx_led_count = g_dmx512_led_controller.config.dmx_led_count;
        if (dmx_led_count > 0) {
            dmx512_set_rgb_array(1, g_dmx512_led_controller.led_colors, dmx_led_count);
            
            /* 发送DMX512数据 */
            if (dmx512_is_transmission_complete()) {
                dmx512_send_frame();
            }
        }
    }
    
    /* 更新WS2812灯带 */
    if (output & DMX512_LED_OUTPUT_WS2812) {
        uint16_t ws2812_led_count = g_dmx512_led_controller.config.ws2812_led_count;
        if (ws2812_led_count > 0) {
            ws2812_set_led_colors(0, g_dmx512_led_controller.led_colors, ws2812_led_count);
            
            /* 发送WS2812数据 */
            if (ws2812_is_transmission_complete()) {
                ws2812_send_data();
            }
        }
    }
    
    g_dmx512_led_controller.last_frame_time = SysTick->VAL;
}

/*!
    \brief      映射DMX512数据到LED颜色
    \param[in]  dmx_data: DMX512数据缓冲区
    \param[in]  dmx_length: DMX512数据长度
    \param[out] led_colors: LED颜色输出缓冲区
    \param[in]  led_count: LED数量
    \param[out] none
    \retval     实际映射的LED数量
*/
uint16_t dmx512_led_controller_map_data(uint8_t *dmx_data, uint16_t dmx_length, 
                                       rgb_color_t *led_colors, uint16_t led_count)
{
    if (dmx_data == NULL || led_colors == NULL || dmx_length == 0 || led_count == 0) {
        return 0;
    }
    
    uint16_t mapped_count = 0;
    
    switch (g_dmx512_led_controller.config.mode) {
        case DMX512_LED_MODE_DIRECT:
            mapped_count = dmx512_led_controller_map_direct(dmx_data, dmx_length, led_colors, led_count);
            break;
            
        case DMX512_LED_MODE_SCALED:
            mapped_count = dmx512_led_controller_map_scaled(dmx_data, dmx_length, led_colors, led_count);
            break;
            
        case DMX512_LED_MODE_REPLICATED:
            mapped_count = dmx512_led_controller_map_replicated(dmx_data, dmx_length, led_colors, led_count);
            break;
            
        case DMX512_LED_MODE_MIXED:
            /* 混合模式：前10个LED使用直接映射，后20个LED使用复制映射 */
            mapped_count = dmx512_led_controller_map_direct(dmx_data, dmx_length, led_colors, 10);
            if (led_count > 10) {
                uint16_t replicated_count = dmx512_led_controller_map_replicated(dmx_data, dmx_length, 
                                                                               &led_colors[10], led_count - 10);
                mapped_count += replicated_count;
            }
            break;
            
        default:
            mapped_count = dmx512_led_controller_map_direct(dmx_data, dmx_length, led_colors, led_count);
            break;
    }
    
    return mapped_count;
}

/*!
    \brief      直接映射模式
    \param[in]  dmx_data: DMX512数据缓冲区
    \param[in]  dmx_length: DMX512数据长度
    \param[out] led_colors: LED颜色输出缓冲区
    \param[in]  led_count: LED数量
    \param[out] none
    \retval     实际映射的LED数量
*/
static uint16_t dmx512_led_controller_map_direct(uint8_t *dmx_data, uint16_t dmx_length, 
                                                rgb_color_t *led_colors, uint16_t led_count)
{
    uint16_t start_channel = g_dmx512_led_controller.config.start_channel;
    uint16_t mapped_count = 0;
    uint16_t channel_index = start_channel;
    
    for (uint16_t i = 0; i < led_count && (channel_index + 2) < dmx_length; i++) {
        led_colors[i].red = dmx_data[channel_index];
        led_colors[i].green = dmx_data[channel_index + 1];
        led_colors[i].blue = dmx_data[channel_index + 2];
        channel_index += 3;
        mapped_count++;
    }
    
    return mapped_count;
}

/*!
    \brief      缩放映射模式
    \param[in]  dmx_data: DMX512数据缓冲区
    \param[in]  dmx_length: DMX512数据长度
    \param[out] led_colors: LED颜色输出缓冲区
    \param[in]  led_count: LED数量
    \param[out] none
    \retval     实际映射的LED数量
*/
static uint16_t dmx512_led_controller_map_scaled(uint8_t *dmx_data, uint16_t dmx_length, 
                                                rgb_color_t *led_colors, uint16_t led_count)
{
    uint16_t start_channel = g_dmx512_led_controller.config.start_channel;
    uint16_t available_channels = (dmx_length - start_channel) / 3;
    uint16_t mapped_count = 0;
    
    if (available_channels == 0) {
        return 0;
    }
    
    /* 将可用的DMX通道缩放到LED数量 */
    for (uint16_t i = 0; i < led_count; i++) {
        uint16_t source_led = (i * available_channels) / led_count;
        uint16_t channel_index = start_channel + source_led * 3;
        
        if ((channel_index + 2) < dmx_length) {
            led_colors[i].red = dmx_data[channel_index];
            led_colors[i].green = dmx_data[channel_index + 1];
            led_colors[i].blue = dmx_data[channel_index + 2];
            mapped_count++;
        } else {
            led_colors[i].red = 0;
            led_colors[i].green = 0;
            led_colors[i].blue = 0;
        }
    }
    
    return mapped_count;
}

/*!
    \brief      复制映射模式
    \param[in]  dmx_data: DMX512数据缓冲区
    \param[in]  dmx_length: DMX512数据长度
    \param[out] led_colors: LED颜色输出缓冲区
    \param[in]  led_count: LED数量
    \param[out] none
    \retval     实际映射的LED数量
*/
static uint16_t dmx512_led_controller_map_replicated(uint8_t *dmx_data, uint16_t dmx_length, 
                                                    rgb_color_t *led_colors, uint16_t led_count)
{
    uint16_t start_channel = g_dmx512_led_controller.config.start_channel;
    uint16_t mapped_count = 0;
    
    /* 使用第一个RGB数据复制到所有LED */
    if ((start_channel + 2) < dmx_length) {
        rgb_color_t base_color;
        base_color.red = dmx_data[start_channel];
        base_color.green = dmx_data[start_channel + 1];
        base_color.blue = dmx_data[start_channel + 2];
        
        for (uint16_t i = 0; i < led_count; i++) {
            led_colors[i] = base_color;
            mapped_count++;
        }
    }
    
    return mapped_count;
}

/*!
    \brief      应用亮度调整
    \param[in,out] colors: LED颜色数组
    \param[in]  count: LED数量
    \param[in]  brightness: 亮度值(0-255)
    \param[out] none
    \retval     none
*/
void dmx512_led_controller_apply_brightness(rgb_color_t *colors, uint16_t count, uint8_t brightness)
{
    if (colors == NULL || brightness == 255) {
        return; /* 无需调整 */
    }
    
    for (uint16_t i = 0; i < count; i++) {
        colors[i].red = (colors[i].red * brightness) / 255;
        colors[i].green = (colors[i].green * brightness) / 255;
        colors[i].blue = (colors[i].blue * brightness) / 255;
    }
}

/*!
    \brief      DMX512帧接收回调函数
    \param[in]  data: 接收到的数据
    \param[in]  length: 数据长度
    \param[out] none
    \retval     none
*/
static void dmx512_led_controller_dmx_frame_callback(uint8_t *data, uint16_t length)
{
    /* 适度输出调试信息 */
    static uint32_t callback_counter = 0;
    callback_counter++;
    
    /* 每5次回调输出一次 */
    if (callback_counter % 5 == 0) {
        printf("\r\n[DEBUG] DMX512帧回调: 长度=%d", length);
    }
    
    (void)data;
    /* 帧处理在主循环中的dmx512_led_controller_process_frame()中进行 */
}

/*!
    \brief      DMX512错误回调函数
    \param[in]  error: 错误类型
    \param[out] none
    \retval     none
*/
static void dmx512_led_controller_dmx_error_callback(dmx512_rx_error_t error)
{
    const char *error_msg = dmx512_rx_get_error_string(error);
    
    if (g_dmx512_led_controller.error_callback != NULL) {
        g_dmx512_led_controller.error_callback(error_msg);
    }
    
    printf("\r\nDMX512接收错误: %s", error_msg);
}

/*!
    \brief      更新统计信息
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void dmx512_led_controller_update_stats(void)
{
    static uint32_t last_update_time = 0;
    static uint32_t last_frame_count = 0;
    
    uint32_t current_time = SysTick->VAL;
    g_dmx512_led_controller.stats.last_update_time = current_time;
    
    /* 计算更新频率(每秒更新一次) */
    if ((current_time - last_update_time) >= 1000) {
        uint32_t frame_diff = g_dmx512_led_controller.stats.frames_updated - last_frame_count;
        g_dmx512_led_controller.stats.update_rate = frame_diff;
        
        last_update_time = current_time;
        last_frame_count = g_dmx512_led_controller.stats.frames_updated;
    }
}

/* 配置和状态函数实现 */

void dmx512_led_controller_set_mode(dmx512_led_mode_t mode)
{
    g_dmx512_led_controller.config.mode = mode;
}

void dmx512_led_controller_set_output(dmx512_led_output_t output)
{
    g_dmx512_led_controller.config.output = output;
}

void dmx512_led_controller_set_brightness(uint8_t brightness)
{
    g_dmx512_led_controller.config.brightness = brightness;
}

void dmx512_led_controller_set_start_channel(uint16_t start_channel)
{
    if (start_channel >= 1 && start_channel <= 512) {
        g_dmx512_led_controller.config.start_channel = start_channel;
    }
}

void dmx512_led_controller_enable(bool enabled)
{
    if (enabled) {
        dmx512_led_controller_start();
    } else {
        dmx512_led_controller_stop();
    }
}

bool dmx512_led_controller_is_enabled(void)
{
    return g_dmx512_led_controller.enabled;
}

void dmx512_led_controller_get_stats(dmx512_led_stats_t *stats)
{
    if (stats != NULL) {
        memcpy(stats, &g_dmx512_led_controller.stats, sizeof(dmx512_led_stats_t));
    }
}

void dmx512_led_controller_reset_stats(void)
{
    memset(&g_dmx512_led_controller.stats, 0, sizeof(dmx512_led_stats_t));
}

void dmx512_led_controller_set_frame_callback(void (*callback)(uint16_t led_count, rgb_color_t *colors))
{
    g_dmx512_led_controller.frame_update_callback = callback;
}

void dmx512_led_controller_set_error_callback(void (*callback)(const char *error_msg))
{
    g_dmx512_led_controller.error_callback = callback;
}

bool dmx512_led_controller_data_changed(void)
{
    bool changed = s_data_changed;
    s_data_changed = false;
    return changed;
}

rgb_color_t dmx512_led_controller_get_led_color(uint16_t led_index)
{
    if (led_index < DMX512_LED_MAX_LEDS) {
        return g_dmx512_led_controller.led_colors[led_index];
    }
    return (rgb_color_t){0, 0, 0};
}

void dmx512_led_controller_set_led_color(uint16_t led_index, rgb_color_t color)
{
    if (led_index < DMX512_LED_MAX_LEDS) {
        g_dmx512_led_controller.led_colors[led_index] = color;
    }
}

/* 字符串描述函数 */

const char* dmx512_led_controller_get_mode_string(dmx512_led_mode_t mode)
{
    switch (mode) {
        case DMX512_LED_MODE_DIRECT:
            return "直接映射";
        case DMX512_LED_MODE_SCALED:
            return "缩放映射";
        case DMX512_LED_MODE_REPLICATED:
            return "复制映射";
        case DMX512_LED_MODE_MIXED:
            return "混合映射";
        default:
            return "未知模式";
    }
}

const char* dmx512_led_controller_get_output_string(dmx512_led_output_t output)
{
    switch (output) {
        case DMX512_LED_OUTPUT_NONE:
            return "无输出";
        case DMX512_LED_OUTPUT_DMX512:
            return "DMX512灯带";
        case DMX512_LED_OUTPUT_WS2812:
            return "WS2812灯带";
        case DMX512_LED_OUTPUT_BOTH:
            return "两种灯带";
        default:
            return "未知输出";
    }
}

/* 预定义配置函数 */

void dmx512_led_controller_get_default_config(dmx512_led_config_t *config)
{
    if (config != NULL) {
        config->mode = DMX512_LED_MODE_DIRECT;
        config->output = DMX512_LED_OUTPUT_BOTH;
        config->start_channel = DMX512_LED_START_CHANNEL;
        config->channel_count = DMX512_LED_MAX_CHANNELS;
        config->dmx_led_count = DMX512_LED_DMX_OUTPUT_LEDS;
        config->ws2812_led_count = DMX512_LED_WS2812_LEDS;
        config->brightness = 255;
        config->auto_update = true;
        config->update_interval_ms = 25;
    }
}

void dmx512_led_controller_get_direct_config(dmx512_led_config_t *config)
{
    dmx512_led_controller_get_default_config(config);
    if (config != NULL) {
        config->mode = DMX512_LED_MODE_DIRECT;
    }
}

void dmx512_led_controller_get_replicated_config(dmx512_led_config_t *config)
{
    dmx512_led_controller_get_default_config(config);
    if (config != NULL) {
        config->mode = DMX512_LED_MODE_REPLICATED;
        config->channel_count = 3; /* 只需要3个通道 */
    }
}